//
//  KADeviceTool.swift
//  kano
//
//  Created by Frank on 2024/10/8.
//

import Foundation
import AdSupport
import AppTrackingTransparency
import SystemConfiguration
import MachO
import Foundation
import SystemConfiguration.CaptiveNetwork
import Network


class KADeviceTool {
    
    class func isJailbroken() -> String {
        let jailbreakPaths = [
            "/Applications/Cydia.app",
            "/Library/MobileSubstrate/MobileSubstrate.dylib",
            "/bin/bash",
            "/usr/sbin/sshd",
            "/etc/apt",
            "/private/var/lib/apt/",
            "/private/var/stash"
        ]
        for path in jailbreakPaths {
            if FileManager.default.fileExists(atPath: path) {
                return "true"
            }
        }
        do {
            try "test".write(to: URL(fileURLWithPath: "/private/test.txt"), atomically: true, encoding: .utf8)
            try FileManager.default.removeItem(atPath: "/private/test.txt")
            return "true"
        } catch {
            return "false"
        }
    }
    
    class func ka_getIPAddress(_ isipv4: Bool) -> String {
        var addresses = [String: String]()
        
        // Get list of all interfaces on the local machine:
        var ifaddr: UnsafeMutablePointer<ifaddrs>? = nil
        guard getifaddrs(&ifaddr) == 0 else { return "" }
//        guard let firstAddr = ifaddr else { return "" }
        
        // For each interface ...
        for ifptr in sequence(first: ifaddr!, next: { $0.pointee.ifa_next }) {
            let interface = ifptr.pointee
            
            // Check for IPv4 or IPv6 interface:
            let addrFamily = interface.ifa_addr.pointee.sa_family
            if addrFamily == UInt8(AF_INET) || addrFamily == UInt8(AF_INET6) {
                
                // Convert interface name to String:
                let name = String(cString: interface.ifa_name)
//                print("ip name: \(name)")
                if name == "en0" || name == "pdp_ip0" {
                    // Convert interface address to a human readable string:
                    var addr = interface.ifa_addr.pointee
                    var hostname = [CChar](repeating: 0, count: Int(NI_MAXHOST))
                    getnameinfo(&addr, socklen_t(interface.ifa_addr.pointee.sa_len),
                                &hostname, socklen_t(hostname.count),
                                nil, socklen_t(0), NI_NUMERICHOST)
                    let address = String(cString: hostname)
                    print("ip name: \(name)")
//                    guard address.isEmpty == false else { continue }
                    if addrFamily == UInt8(AF_INET) {
                        addresses["IPv4"] = address
                        print("-------IPv4 address: \(address)")
                    } else if addrFamily == UInt8(AF_INET6) {
                        addresses["IPv6"] = address
//                        print("ip name: \(name)")
                        print("-------IPv6 address: \(address)")
                    }
                }
            }
        }
        
        freeifaddrs(ifaddr)
        print("addre\(addresses)")
        if isipv4 {
            return addresses["IPv4"] ?? ""
        }else{
            return addresses["IPv6"] ?? ""
        }
    }

    
    class func ka_iPv4Address() -> String {
        ka_getIPAddress(true)
    }
    
    class func ka_iPv6Address() -> String {
        ka_getIPAddress(false)
    }
    
    class func ka_getSysInfo(typeSpecifier: Int32) -> UInt {
        var size = MemoryLayout<Int>.size
        var result: Int = 0
        var mib = [CTL_HW, typeSpecifier]
        
        let status = sysctl(&mib, u_int(mib.count), &result, &size, nil, 0)
        
        guard status == 0 else {
            // Handle the error, for example by returning 0 or throwing an exception
            return 0
        }
        
        return UInt(result)
    }

    class func ka_ramInfo() -> String{
        let ramSize = ka_getSysInfo(typeSpecifier: HW_MEMSIZE)
        return "\(ramSize)"
    }
    
    class func ka_cpuNumber() -> String{
        let cpuInfo = ka_getSysInfo(typeSpecifier: HW_NCPU)
        return "\(cpuInfo)"
    }
}
